﻿using Dm.parser;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MQTT.Server.ExtensionServer.MQTTClient;
using MQTT.Server.GlobalConfig;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
using MQTTnet.Server;
using SqlSugar;

namespace MQTT.Server.Controllers
{
    public class MqttClientController : IMqttClientHostedService
    {
        private readonly ISqlSugarClient _sqlSugar;

        private readonly AppConfig _appConfig;

        private readonly IWebHostEnvironment _environment;

        private readonly ILogger<MqttClientController> _logger;

        private readonly IMqttClient _mqttClient;

        private readonly MqttClientOptions _clientOption;

        public MqttClientController(ISqlSugarClient sqlSugar,
                              AppConfig appConfig,
                              IWebHostEnvironment environment,
                              ILogger<MqttClientController> logger,
                              MqttClientOptions clientOption)

        {
            _sqlSugar = sqlSugar;
            _appConfig = appConfig;
            _environment = environment;
            _logger = logger;
            _clientOption = clientOption;
            _mqttClient = new MqttFactory().CreateMqttClient();

            _mqttClient.ConnectedAsync += OnConnectedAsync;
            _mqttClient.DisconnectedAsync += OnDisconnectedAsync;
            _mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceivedAsync;
        }


        #region Client


        public Task OnApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs args)
        {
            _logger.LogDebug("OnApplicationMessageReceivedAsync");

            return Task.CompletedTask;
        }

        public Task OnDisconnectedAsync(MqttClientDisconnectedEventArgs args)
        {
            _logger.LogInformation("MQTT客户端与服务端断开连接，正在尝试重新连接");
            if (!_mqttClient.IsConnected)
            {
                StartAsync(new CancellationToken());
            }
            return Task.CompletedTask;
        }

        /// <summary>
        /// 请求建立连接前
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public Task OnConnectingAsync(MqttClientConnectingEventArgs args)
        {
            _logger.LogDebug("OnConnectingAsync");

            return Task.CompletedTask;
        }

        /// <summary>
        /// 成功建立连接
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public Task OnConnectedAsync(MqttClientConnectedEventArgs args)
        {
            _logger.LogDebug("OnConnectedAsync");

            _mqttClient.SubscribeAsync("hello/word");



            return Task.CompletedTask;
        }

        /// <summary>
        /// 启动服务不能等待
        /// 程序运行时，MQTT服务端还未启动
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task StartAsync(CancellationToken cancellationToken)
        {
            Task.Run(() =>
            {
                try
                {
                    _mqttClient.ConnectAsync(_clientOption);

                    _logger.LogInformation("建立连接完成");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "建立连接过程中发送了异常");
                }
            });
            return Task.CompletedTask;
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested && _mqttClient.IsConnected)
            {
                var disconnectOption = new MqttClientDisconnectOptions
                {
                    Reason = MqttClientDisconnectOptionsReason.NormalDisconnection,
                    ReasonString = "NormalDiconnection"
                };
                await _mqttClient.DisconnectAsync(disconnectOption, cancellationToken);
            }            
        }

        public IActionResult PublishMessage(string topic, string msg)
        {
            _mqttClient.PublishAsync(new MqttApplicationMessageBuilder()
                                    .WithTopic("hello/world").WithPayload("HelloWord")
                                    .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).Build());
            var content = new ContentResult();
            content.StatusCode = 200;
            content.Content = "成功";
            content.ContentType = "text/plain";
            return content;

        }



        #endregion
    }
}
